home *** CD-ROM | disk | FTP | other *** search
/ FM Towns: Free Software Collection 11 / FM Towns Free Software Collection 11.iso / t_os / tool / dolmorph / src / domorph.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-01-23  |  18.2 KB  |  619 lines

  1. /*===========================================
  2.           DolphMorph(ドルフモーフ)
  3.  
  4.       モーフィング&変形アニメ作成ソフト
  5.  
  6.   モーフィングアルゴリズム: EAST 1994
  7.   インターフェース作成:     松内 良介 1994
  8. ===========================================*/
  9. /*
  10.     EAST氏によるモーフィングアルゴリズム
  11.  
  12.     速度測定:    1994.9.6-00        1.15 clocks/loop
  13.                 1994.9.6-01        1.17 clocks/loop
  14.                 1994.9.6-02        1.07 clocks/loop
  15.                 1994.9.6-03        1.00 clocks/loop
  16.                 1994.9.6-04        0.91 clocks/loop
  17.                 1994.9.6-05        1.08 clocks/loop (座標バッファを動的確保)
  18.                     誰かもっと速くしてくれ~(笑)
  19.  
  20.             void    morphInitialize(int width, int height, float limit,
  21.                                     LIST *plMORPHPOINT, LIST *plMORPHLINE)
  22.             void    morphTerminate()
  23.  
  24.     static    void    do_line3(int x1,int y1,int t1, int x2,int y2,int t2,
  25.                              void func(int x,int y,int t)!)
  26.     static    void    morphSetInit(void)
  27.  
  28.             int        morphExec(float time, int (*func)(MORPH_INFO *info),
  29.                               int callCnt, int do_type)
  30.             void    morphGetColor(int x, int y,  int *r, int *g, int *b)
  31.             void    morphDumpOut(char *filename, int wid, int ht)
  32. */
  33.  
  34. #define    CALLOC    TL_calloc
  35. #define    FREE    TL_free
  36.  
  37. #include <stdio.h>
  38. #include <stdlib.h>
  39. #include <string.h>
  40. #include <winb.h>
  41. #include <te.h>
  42. #include <fntb.h>
  43. #include <gui.h>
  44. #include <file_dlg.h>
  45. #include <egb.h>
  46. #include <ryosuke.h>
  47. #include <usrlib.h>
  48. #include <time.h>
  49. #include <math.h>
  50.  
  51. #include "domorph.h"
  52. #include "fifo.h"
  53.  
  54. #include "morphgo.h"
  55.  
  56. #define    _lim(a, min, max)    (_min(_max((min),(a)), (max)))
  57.  
  58. /*--------------------------------------------------------*/
  59. /*                    モジュール内変数                    */
  60. /*--------------------------------------------------------*/
  61.  
  62.     static LIST *plPOINT;
  63.     static LIST *plLINE;
  64.     // static MORPH_POINT *p;
  65.     // static int morph_point_num = 0;
  66.     // static MORPH_LINE *l;
  67.     // static int morph_line_num = 0;
  68.  
  69.     static fxp  *from_x;
  70.     static fxp  *from_y;
  71.     static fxp  *to_x;
  72.     static fxp  *to_y;
  73.         /*  ↑from_x,from_y,to_x,to_y : 対応座標バッファ
  74.               横方向の要素数が morph_width+2, 縦方向の要素数が morph_height+2
  75.               の2次元配列のイメージ。
  76.               ただ実際には、morphInitialize 内で、1次元配列としてメモリ領域を
  77.               動的確保している。
  78.               中間画像上の点(x,y) について、
  79.                     (from_x[1+y][1+x], from_y[1+y][1+x])=画像Aに対応する座標
  80.                     (to_x[1+y][1+x], to_y[1+y][1+x])    =画像Bに対応する座標
  81.               を表す。 */
  82.     static fxp  *tmp;
  83.         /*  ↑対応座標の収束計算のための一時バッファ。*/
  84.     static char    *mask;
  85.         /*  ↑対応座標の移動不可を表すフラグ。
  86.                 mask[1+y][1+x] が 0 なら…中間画像内(x,y)の対応座標は移動可
  87.                 mask[1+y][1+x] が 1 なら…中間画像内(x,y)の対応座標は移動不可
  88.               これは、収束計算のときに境界点を移動させないために用いる。 */
  89.     static int  BUFWID;
  90.         /*  ↑from_x,from_y,to_x,to_y,mask,tmp の横要素数
  91.               これは morph_width+2 に設定される。*/
  92.     static fxp morph_limit = 0x10000;
  93.         /* ↑対応座標の収束計算時の限界移動量
  94.           (この値よりも移動量が小さくなったら計算を終了する)
  95.            morphInitialize で設定。 */
  96.     static int morph_width,morph_height;
  97.         /*  ↑モーフィング画像の横・縦のピクセル数
  98.               morphInitialize で設定 */
  99.     static fxp morph_t1 = UNIT;
  100.     static fxp morph_t2 = 0;
  101.         /*  ↑現在計算中の中間画像の、画像A/B間での分率。
  102.               0x00000~0x10000 の値をとる(16ビット固定小数点)
  103.               morphExec で設定 */
  104.     static int morphType;
  105.         /*  DO_MORPH , DO_TRANSFORM  */
  106.  
  107.     #define    INDEX(x,y)    ((1+(x)) + BUFWID * (1+(y)))
  108.     #define    IA(name,n)    *((int*)(name) + (n))
  109.     #define    CA(name,n)    *((char*)(name) + (n))
  110.  
  111. /* ユーザー定義された色読み込み関数の外部定義 */
  112.     extern int morphGetFromPixel(fxp x,fxp y,int *r,int *g,int *b);
  113.     extern int morphGetToPixel(fxp x,fxp y,int *r,int *g,int *b);
  114.  
  115. /*--------------------------------------------------------*/
  116. /*             モーフィング処理の初期化/終了             */
  117. /*--------------------------------------------------------*/
  118.  
  119.     void morphInitialize(int width, int height, float limit,
  120.                          LIST *plMORPHPOINT, LIST *plMORPHLINE)
  121.     {
  122.         morph_width = width;
  123.         morph_height = height;
  124.         morph_limit = FP2FX(limit);
  125.         plPOINT = plMORPHPOINT;
  126.         plLINE  = plMORPHLINE;
  127.         // morph_point_num = point_num;
  128.         // p = point;
  129.         // morph_line_num = line_num;
  130.         // l = line;
  131.         from_x = (fxp*)CALLOC(sizeof(fxp), (width+2)*(height+2));
  132.         from_y = (fxp*)CALLOC(sizeof(fxp), (width+2)*(height+2));
  133.         to_x   = (fxp*)CALLOC(sizeof(fxp), (width+2)*(height+2));
  134.         to_y   = (fxp*)CALLOC(sizeof(fxp), (width+2)*(height+2));
  135.         tmp    = (fxp*)CALLOC(sizeof(fxp), (width+2)*(height+2));
  136.         mask   = (char*)CALLOC(sizeof(char), (width+2)*(height+2));
  137.         BUFWID = width + 2;
  138.     }
  139.  
  140.     void morphTerminate()
  141.     {
  142.         FREE(from_x);
  143.         FREE(from_y);
  144.         FREE(to_x);
  145.         FREE(to_y);
  146.         FREE(tmp);
  147.         FREE(mask);
  148.     }
  149.  
  150. /*--------------------------------------------------------*/
  151. /*                    線分アルゴリズム                    */
  152. /*--------------------------------------------------------*/
  153.  
  154.     static void do_line3(int x1,int y1,int t1, int x2,int y2,int t2,
  155.                          void func(int x,int y,int t)!)
  156.     /* (x1,y1)~(x2,y2) の直線上の各点を求める。その際、始点 で t1、
  157.         終点で t2 となるような値 t も同時に求め、各点について関数
  158.         func (x,y,t) を呼び出す。*/
  159.     {
  160.         int xr,yr,tr,dx,dy,dt,x,y,t;
  161.         xr=abs(x2-x1),yr=abs(y2-y1),tr=abs(t2-t1);
  162.         func(x1,y1,t1);    // 最初の点
  163.         if (xr==0 && yr==0)
  164.             ;
  165.         else if (xr >= yr)
  166.         {
  167.             dy = (yr<<16) / xr;   if(y1>y2)  dy = -dy;
  168.             dt = (tr<<16) / xr;   if(t1>t2)  dt = -dt;
  169.             if (x1 < x2)
  170.                 for (x=x1+1, y=(y1<<16)+0x8000+dy, t=(t1<<16)+0x8000+dt;
  171.                      x <= x2;  x++, y+=dy, t+=dt)
  172.                     func(x,y>>16,t>>16);
  173.             else
  174.                 for (x=x1-1, y=(y1<<16)+0x8000+dy, t=(t1<<16)+0x8000+dt;
  175.                      x >= x2;  x--, y+=dy, t+=dt)
  176.                     func(x,y>>16,t>>16);
  177.         }
  178.         else
  179.         {
  180.             dx = (xr<<16) / yr;   if(x1>x2)  dx = -dx;
  181.             dt = (tr<<16) / yr;   if(t1>t2)  dt = -dt;
  182.             if (y1 < y2)
  183.                 for (y=y1+1, x=(x1<<16)+0x8000+dx, t=(t1<<16)+0x8000+dt;
  184.                      y <= y2;  y++, x+=dx, t+=dt)
  185.                     func(x>>16,y,t>>16);
  186.             else
  187.                 for (y=y1-1, x=(x1<<16)+0x8000+dx, t=(t1<<16)+0x8000+dt;
  188.                      y >= y2;  y--, x+=dx, t+=dt)
  189.                     func(x>>16,y,t>>16);
  190.         }
  191.     }
  192.  
  193. /*--------------------------------------------------------*/
  194. /*                     境界条件の設定                     */
  195. /*--------------------------------------------------------*/
  196.  
  197.     static void morphSetInit(void)
  198.     {
  199.         // printf("morphSetInit begin\n");
  200.         int x,y,idx;
  201.       /* 対応座標配列を初期化 */
  202.         for (y=-1; y<=morph_height; y++)
  203.             for (x=-1,idx=INDEX(x,y); x<=morph_width; x++,idx++)
  204.             {
  205.                 mask  [idx] = (0 <= x && x < morph_width &&
  206.                                0 <= y && y < morph_height ? 0 : 1);
  207.                 from_x[idx] = I2FX(x);
  208.                 from_y[idx] = I2FX(y);
  209.                 to_x  [idx] = I2FX(x);
  210.                 to_y  [idx] = I2FX(y);
  211.             }
  212.       /* 点タイプの境界条件設定 */
  213.         if (plPOINT == NULL)
  214.             goto NOPOINT;
  215.         for (list_top(plPOINT); !list_isOut(plPOINT); list_next(plPOINT))
  216.         {
  217.             MORPH_POINT mp;
  218.             list_getData(plPOINT,&mp);
  219.           /* 中間画像上での境界点の座標を計算 */
  220.             x = FX2I(mp.from.x * morph_t1 + mp.to.x * morph_t2);
  221.             y = FX2I(mp.from.y * morph_t1 + mp.to.y * morph_t2);
  222.             x = _lim(x,0,morph_width-1);
  223.             y = _lim(y,0,morph_height-1);
  224.           /* 境界点について、画像A/Bへの対応座標を設定 */
  225.             // printf("  morphSetInit (point %d,%d  from=%d,%d  to=%d,%d)\n",
  226.             //         x,y, mp.from.x, mp.from.y, mp.to.x, mp.to.y);
  227.             idx = INDEX(x,y);
  228.             from_x[idx] = I2FX(mp.from.x);
  229.             from_y[idx] = I2FX(mp.from.y);
  230.             to_x  [idx] = I2FX(mp.to.x);
  231.             to_y  [idx] = I2FX(mp.to.y);
  232.             mask  [idx] = 1;    /* 境界点では対応座標は移動させない */
  233.         }
  234.        NOPOINT:;
  235.       /* 線指定境界条件の設定 */
  236.         if (plLINE == NULL)
  237.             goto NOLINE;
  238.         for (list_top(plLINE); !list_isOut(plLINE); list_next(plLINE))
  239.         {
  240.             // printf("  morphSetInit (line)\n");
  241.             MORPH_LINE ml;
  242.             list_getData(plLINE, &ml);
  243.             int    tx1,ty1,tx2,ty2;
  244.             #define    L    ml
  245.           /* 中間画像上での境界線分の始点・終点座標を計算 */
  246.             tx1 = FX2I(L.from1.x * morph_t1 + L.to1.x * morph_t2);
  247.             ty1 = FX2I(L.from1.y * morph_t1 + L.to1.y * morph_t2);
  248.             tx2 = FX2I(L.from2.x * morph_t1 + L.to2.x * morph_t2);
  249.             ty2 = FX2I(L.from2.y * morph_t1 + L.to2.y * morph_t2);
  250.           /* 境界線分上の点ついて、画像A/Bへの対応座標を設定する関数 */
  251.             void pset(int x,int y,int s)
  252.                 /* (x,y):境界線分上の点の座標
  253.                    s:0x0000(始点)~0x1000(終点) 線分のなかのどの位置か
  254.                                                 (12ビット固定少数点)     */
  255.             {
  256.                 int r;
  257.                 r = 0x1000 - s;
  258.                 idx = INDEX(x,y);
  259.                   /* r,s は12bit固定小数点だが、求めるべき対応座標は16bit
  260.                      固定小数点なので、4ビット上位へシフトしてから代入 */
  261.                 from_x[idx] = (L.from1.x * r + L.from2.x * s) << 4;
  262.                 from_y[idx] = (L.from1.y * r + L.from2.y * s) << 4;
  263.                 to_x  [idx] = (L.to1.x   * r + L.to2.x   * s) << 4;
  264.                 to_y  [idx] = (L.to1.y   * r + L.to2.y   * s) << 4;
  265.                 mask  [idx] = 1;
  266.             }
  267.           /* 境界線分上の各点について、対応座標を設定 */
  268.             do_line3(tx1,ty1,0x0000,  tx2,ty2,0x1000,  pset);
  269.             #undef L
  270.         }
  271.        NOLINE:;
  272.        END:;
  273.         // printf("morphSetInit end\n");
  274.         return;
  275.     }
  276.  
  277. /*--------------------------------------------------------*/
  278. /*                   初期対応座標の設定                   */
  279. /*--------------------------------------------------------*/
  280.  
  281.     static void morphSetFromTo(void)
  282.     {
  283.       /* x 方向 */
  284.         int x,y;
  285.         for (y=0; y<morph_height; y++)
  286.         {
  287.             int idx0;
  288.             int left;
  289.             idx0 = INDEX(0,y);
  290.             left = -1;
  291.             for (x=-1; x<=morph_width; )
  292.             {
  293.                 if (mask[idx0+x] == 0)
  294.                     x++;
  295.                 else
  296.                 {
  297.                   // それまでの非マスク領域について、マスク座標を内分
  298.                     if (x > left)
  299.                     {
  300.                         int fx1,fx2,tx1,tx2;
  301.                         fx1 = (from_x[idx0+left] + 128) >> 8; // 8bit fixed.p.
  302.                         fx2 = (from_x[idx0+   x] + 128) >> 8;
  303.                         tx1 = (to_x  [idx0+left] + 128) >> 8;
  304.                         tx2 = (to_x  [idx0+   x] + 128) >> 8;
  305.                         int k,ip,ipwid,h;
  306.                         ipwid = x-left;
  307.                         h = ipwid / 2;
  308.                         for (k=left+1,ip=1; k<=x-1; k++,ip++)
  309.                         {
  310.                           from_x[idx0+k]=((fx1*(ipwid-ip)+fx2*ip+h)/ipwid)<<8;
  311.                           to_x  [idx0+k]=((tx1*(ipwid-ip)+tx2*ip+h)/ipwid)<<8;
  312.                         }
  313.                     }
  314.                     while (mask[idx0+x] == 1 && x <= morph_width)
  315.                         x++;
  316.                     left = x-1;
  317.                 }
  318.             }
  319.         }
  320.       /* y 方向 */
  321.         for (x=0; x<morph_width; x++)
  322.         {
  323.             int idx0;
  324.             int top;
  325.             idx0 = INDEX(x,0);
  326.             top = 0;
  327.             for (y=-1; y<=morph_height; )
  328.             {
  329.                 if (mask[idx0+BUFWID*y] == 0)
  330.                     y++;
  331.                 else
  332.                 {
  333.                   // それまでの非マスク領域について、マスク座標を内分
  334.                     if (y > top)
  335.                     {
  336.                         int fy1,fy2,ty1,ty2;
  337.                         fy1 = (from_y[idx0+BUFWID * top] + 128) >> 8;
  338.                         fy2 = (from_y[idx0+BUFWID *   y] + 128) >> 8;
  339.                         ty1 = (to_y  [idx0+BUFWID * top] + 128) >> 8;
  340.                         ty2 = (to_y  [idx0+BUFWID *   y] + 128) >> 8;
  341.                         int k,ip,ipwid,h;
  342.                         ipwid = y-top;
  343.                         h = ipwid / 2;
  344.                         for (k=top+1,ip=1; k<=y-1; k++,ip++)
  345.                         {
  346.                           from_y[idx0+BUFWID*k] =
  347.                             ((fy1*(ipwid-ip)+fy2*ip+h)/ipwid) << 8;
  348.                           to_y  [idx0+BUFWID*k] =
  349.                             ((ty1*(ipwid-ip)+ty2*ip+h)/ipwid) << 8;
  350.                         }
  351.                     }
  352.                     while (mask[idx0+BUFWID*y] == 1 && y <= morph_height)
  353.                         y++;
  354.                     top = y - 1;
  355.                 }
  356.             } // for y
  357.         } // for x
  358.     }
  359.  
  360. /*--------------------------------------------------------*/
  361. /*                   対応座標の収束計算                   */
  362. /*--------------------------------------------------------*/
  363.  
  364.     int morphExec(float time, int (*func)(MORPH_INFO *info), int callCnt,
  365.                    int do_type)
  366.     /* morphInitialize 呼び出しの後にこの関数を呼び出すことで、
  367.        対応座標(from_x,from_y,to_x,to_y)の収束計算が行われる。 */
  368.     /* 引数 time には、画像A/B間の分率を 0.0 ~ 1.0 の値で設定する。
  369.        つまり、0.0 を設定すると画像Aそのものが、1.0 を設定すると画像B
  370.        そのものが得られる */
  371.     /* do_type : DO_MORPH / DO_TRANSFORM */
  372.     /* この関数を実行後、morphGetColor により、中間画像の各ピクセルを
  373.        得ることができる。*/
  374.     /* 収束計算の途中で、callCnt 回のループごとに関数 func を呼び出す
  375.        関数 func が0以外の値を返せば、計算を中断 */
  376.     /* 返値  0=通常終了  -1=中断された */
  377.  
  378.     {
  379.         int    vv;
  380.         morphType = (do_type == DO_TRANSFORM ? DO_TRANSFORM : DO_MORPH);
  381.       /* 中間画像の画像A/B間での分率を morph_t1, morph_t2 に設定
  382.          (12ビット固定小数点) */
  383.         morph_t2 = FP2FX(time);
  384.         morph_t2 = _lim(morph_t2, 0, UNIT);
  385.         morph_t1 = UNIT - morph_t2;
  386.       /* 境界条件の指定 */
  387.         morphSetInit();
  388.       /* 初期対応座標の設定 */
  389.         morphSetFromTo();
  390.       /* 収束計算 (vv ごとに、from_x, from_y, to_x, to_y の順) */
  391.         for (vv=0; vv<(morphType == DO_TRANSFORM ? 2 : 4); vv++)
  392.         {
  393.             int    i;
  394.             int    flag;
  395.             int *var;
  396.           /* 無視して良い計算は無視。 */
  397.             if (morphType == DO_MORPH)
  398.             {
  399.                 if (morph_t1 == 0 && (vv==0||vv==1))
  400.                     continue;
  401.                 if (morph_t2 == 0 && (vv==2||vv==3))
  402.                     continue;
  403.             }
  404.             var = (vv==0 ? from_x : vv==1 ? from_y :
  405.                    vv==2 ? to_x : to_y);
  406.             unsigned int clk1,clk2;
  407.             clk1 = clock();    // 実行時間計測開始
  408.             int callCheck;
  409.             callCheck = 0;
  410.             for (i=0;i<=10000;i++)
  411.             {
  412.                 int x,y,idx;
  413.               /* 中間画像内の全ての点について、その点の対応座標を再計算
  414.                  (その点の上下左右の点に設定されている対応座標の平均を、
  415.                   新たな対応座標として計算→いったん tmp に一時登録する) */
  416.                 for (y=0; y<morph_height; y++)
  417.                 {
  418.                   /* まずは横16ピクセルずつまとめて処理 */
  419.                     for (x=0,idx=INDEX(x,y); x+16<=morph_width; x+=16)
  420.                     {
  421.                         int *p;
  422.                         p = var + idx;
  423.                         #define DO                                             \
  424.                           tmp[idx] = (p[-1]+p[1]+p[-BUFWID]+p[BUFWID])>>2;    \
  425.                           p++,idx++;
  426.                         DO DO DO DO  DO DO DO DO
  427.                         DO DO DO DO  DO DO DO DO
  428.                         #undef DO
  429.                     }
  430.                   /*  残りの 0 ~ 15 ピクセルを処理  */
  431.                     for (; x<morph_width; x++,idx++)
  432.                         tmp[idx] = ( var[idx-1] + var[idx+1] +
  433.                                      var[idx-BUFWID] + var[idx+BUFWID] ) >> 2;
  434.                 }
  435.               /* 対応座標の移動可・不可フラグに従い、実際に対応座標を更新 */
  436.               /* 同時に、対応座標の最大移動量 (flag) も求める */
  437.                 flag = 0;
  438.                 for (y=0; y<morph_height; y++)
  439.                 {
  440.                 #if 1
  441.                   /* まずは横8ピクセルずつまとめて処理 */
  442.                     for(x=0,idx=INDEX(x,y); x+8<=morph_width; x+=8)
  443.                     {
  444.                         #define DO                                    \
  445.                             if(mask[idx] == 0)                        \
  446.                             {                                        \
  447.                                 int f;                                \
  448.                                 f = abs(tmp[idx] - var[idx]);        \
  449.                                 if (f > flag)  flag = f;            \
  450.                                 var[idx] = tmp[idx];                \
  451.                             }                                        \
  452.                             idx++;
  453.                         DO DO DO DO DO DO DO DO
  454.                         #undef DO
  455.                     }
  456.                   /* 残りの0~7ピクセルを処理 */
  457.                     for (; x<morph_width; x++,idx++)
  458.                     {
  459.                         if(mask[idx] == 0)
  460.                         {
  461.                             int f = abs(tmp[idx] - var[idx]);
  462.                             if (f > flag)  flag = f;
  463.                             var[idx] = tmp[idx];
  464.                         }
  465.                     }
  466.                 #else
  467.                   /* まずは横8ピクセルずつまとめて処理 */
  468.                     for(x=0,idx=INDEX(x,y); x+8<=morph_width; )
  469.                     {
  470.                         #define DO                                    \
  471.                             if(mask[idx] == 0)                        \
  472.                             {                                        \
  473.                                 int f;                                \
  474.                                 f = abs(tmp[idx] - var[idx]);        \
  475.                                 if (f > flag)  flag = f;            \
  476.                                 var[idx] = tmp[idx];                \
  477.                             }                                        \
  478.                             else if (i==0||i==1||i==2)                    \
  479.                                 ; /* printf("morphExec: point(%d,%d,%3.1f,%3.1f)\n",x,y,FX2FP(var[idx-1]),FX2FP(var[idx+1])); */ \
  480.                             idx++,x++;
  481.                         DO DO DO DO DO DO DO DO
  482.                         #undef DO
  483.                     }
  484.                   /* 残りの0~7ピクセルを処理 */
  485.                     for (; x<morph_width; x++,idx++)
  486.                     {
  487.                         if(mask[idx] == 0)
  488.                         {
  489.                             int f = abs(tmp[idx] - var[idx]);
  490.                             if (f > flag)  flag = f;
  491.                             var[idx] = tmp[idx];
  492.                         }
  493.                         else if (i==0||i==1||i==2)
  494.                             ; /* printf("morphExec: point(%d,%d)\n",x,y); */
  495.                     }
  496.                 #endif
  497.                 }
  498.               /* 対応座標の移動量が小さいなら、収束したということなので終了 */
  499.                 if (flag < morph_limit) break;
  500.                 if (func != 0)
  501.                 {
  502.                     if (callCheck <= 0)
  503.                     {
  504.                         MORPH_INFO info;
  505.                         info.varType = vv;
  506.                         info.loopCnt = i;
  507.                         info.moveMax = flag;
  508.                         info.moveLimit = morph_limit;
  509.                         info.morphType = morphType;
  510.                         if ((*func)(&info) != 0)
  511.                             goto BREAK;
  512.                         callCheck = callCnt;
  513.                     }
  514.                     else
  515.                         callCheck--;
  516.                 }
  517.             }
  518.             // printf("morphExec:\n");
  519.             clk2 = clock();    // 実行時間計測終了
  520.             // if (i >= 200)
  521.             //     printf("loop rate: %lf clocks/loop\n",
  522.             //            (float)(clk2-clk1)/(float)i);
  523.             // printf("%d i=%ld, %lf\n",vv,i,FX2FP(flag));
  524.             // char msg[200];
  525.             // sprintf(msg,"%d i=%ld, %lf\n",vv,i,FX2FP(flag));
  526.             // morphgo_msg(msg);
  527.         }
  528.        END:;
  529.         return 0;
  530.        BREAK:;
  531.         return -1;
  532.     }
  533.  
  534. /*--------------------------------------------------------*/
  535. /*               中間画像の各ピクセルの取得               */
  536. /*--------------------------------------------------------*/
  537.  
  538.     // ★このへんのモジュール分割はむちゃくちゃ。要再考。
  539.  
  540.     void morphGetColor(int x,int y,  int *r,int *g,int *b)
  541.     {
  542.         int idx;
  543.         int r1,g1,b1,r2,g2,b2;
  544.         idx = INDEX(x,y);
  545.         if (morphType == DO_MORPH)
  546.         {
  547.             if (morphgo_getBackFlag())
  548.             {
  549.                 int c;
  550.                 c = morphgo_getBackImagePixel(x,y);
  551.                 if (morphGetFromPixel(from_x[idx],from_y[idx],&r1,&g1,&b1)!=0)
  552.                 {
  553.                     g1 = (c >> 10) & 0x1f;
  554.                     r1 = (c >>  5) & 0x1f;
  555.                     b1 = (c      ) & 0x1f;
  556.                 }
  557.                 if (morphGetToPixel(to_x[idx], to_y[idx], &r2,&g2,&b2) != 0)
  558.                 {
  559.                     g2 = (c >> 10) & 0x1f;
  560.                     r2 = (c >>  5) & 0x1f;
  561.                     b2 = (c      ) & 0x1f;
  562.                 }
  563.             }
  564.             else
  565.             {
  566.                 morphGetFromPixel(from_x[idx],from_y[idx],&r1,&g1,&b1);
  567.                 morphGetToPixel(to_x[idx], to_y[idx], &r2,&g2,&b2);
  568.             }
  569.             *r = FX2I(r1 * morph_t1 + r2 * morph_t2);
  570.             *g = FX2I(g1 * morph_t1 + g2 * morph_t2);
  571.             *b = FX2I(b1 * morph_t1 + b2 * morph_t2);
  572.         }
  573.         else if (morphType == DO_TRANSFORM)
  574.         {
  575.             if (morphgo_getBackFlag())
  576.             {
  577.                 int c;
  578.                 c = morphgo_getBackImagePixel(x,y);
  579.                 if (morphGetFromPixel(from_x[idx], from_y[idx],  r,g,b) != 0)
  580.                 {
  581.                     *g = (c >> 10) & 0x1f;
  582.                     *r = (c >>  5) & 0x1f;
  583.                     *b = (c      ) & 0x1f;
  584.                 }
  585.             }
  586.             else
  587.                 morphGetFromPixel(from_x[idx], from_y[idx],  r,g,b);
  588.         }
  589.         return;
  590.     }
  591.  
  592. /*--------------------------------------------------------*/
  593. /*                 ダンプ出力(デバッグ用)                 */
  594. /*--------------------------------------------------------*/
  595.  
  596.     void morphDumpOut(char *filename,int wid,int ht)
  597.     {
  598.         int *var;
  599.         int x,y,idx;
  600.         var = from_x;
  601.         FILE *fp;
  602.         if ((fp = fopen(filename, "w")) == NULL)
  603.             return;
  604.         for (y=0; y<ht; y++)
  605.         {
  606.             for (x=0,idx=INDEX(x,y); x<wid; x++,idx++)
  607.             {
  608.                 if (mask[idx] == 0)
  609.                     fprintf(fp,"%5.1f ",FX2FP(var[idx]));
  610.                 else
  611.                     fprintf(fp,"%3d * ",FX2I(var[idx]));
  612.             }
  613.             fprintf(fp,"\n");
  614.         }
  615.         fclose(fp);
  616.     }
  617.  
  618. /* [end] */
  619.